/*
 * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
 */

#ifndef __UTIL_H__
#define __UTIL_H__

/*****************************************************************************/
/*  本文件需要包含的其他头文件依赖                                           */
/*****************************************************************************/
#include <QString>
#include "minwindef.h"
#include "LibMain.h"
#include "cwchar"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cpluscplus */
#endif /* __cpluscplus */
    
    
    /*****************************************************************************/
    /*  宏开关定义（例如可能的编译、调试、打印开关）                             */
    /*****************************************************************************/
    
    
    /*****************************************************************************/
    /*  宏常量定义                                                               */
    /*****************************************************************************/
    
#define SHORT_INTV               100 /* 50ms 以下定时间隔 */
#define POINT_CHARACTER          46 /* 小数点 */
#define BROADCAST_IP_SEC1_MAX    239 /* 组播IP地址第一段最大值 */
#define BROADCAST_IP_SEC1_MIN    224 /* 组播IP地址第一段最小值 */
#define MAX_ITEM_LEN             256
#define MAX_PRODUCT_ID_LEN       20
#define MAX_INI_FILE_LEN         (8 * MAX_ITEM_LEN)
    
#define INI_ITEM_IMG_NAME        "IMAGE_NAME"
#define INI_ITEM_IMG_SIZE        "IMAGE_SIZE"
#define INI_ITEM_PKG_ID          "PACKAGE_ID"
#define INI_ITEM_PRDCT_ID        "PRODUCT_ID"
#define INI_ITEM_FIRMWARE_VER    "FIRMWARE_VERSION"
#define INI_ITEM_PCB_VER         "PCB_VERSION"
#define INI_ITEM_FIRMWARE_CRC    "FIRMWARE_CRC_SUM"
#define INI_ITEM_INI_CRC         "INI_CRC_SUM"
#define INI_ITEM_PARTITIONS      "PARTITIONS"
#define MULTICAST_IP             "MULTICAST_IP"
#define INTERVAL_TIME            "INTERVAL_TIME"
#define INI_POSTFIX              ".ini" /* ini扩展名 */
    
    
#define PACKET_TYPE_NORMAL        0x001 /* 普通报文 */
#define PACKET_TYPE_LAST_DATA     0x002 /* 最后一个数据报文 */
#define PACKET_TYPE_DESCRIPTOR    0x003 /* 描述报文 */
    
    
#define MAX_PKG_VERSION_LEN       (24)    /* 包特征描述字符串长度 */
#define MAX_PKG_DATE_LEN          (12)    /* 日期字符串长度 */
#define WMX_UPG_URL_MAX_LEN       (256)   /* 文件服务器URL的最大长度 */
#define WMX_UPG_USERNAME_MAX_LEN  (64)    /* 用户名 */
#define WMX_UPG_PASSWORD_MAX_LEN  (16)    /* 密码 */
    
    /* 升级包内的有效标志位 */
#define UPG_FILE_VALID_FLAG   (0x5A5AA5A5)
#define PKG_HEAD_SIZE             (56)    /* Package 头的大小信息 */
#define PKG_VALID_FLAG_OFFSET     (4)
#define FILE_VALID_FLAG_OFFSET    (56)
    
#define MAX_FILE_ID 50
#define MAX_DISP_NAME 34
#define MAX_UINT_DISP_NAME 32
#define MAX_UNLOCK_CODE 8
    
#define MAX_SW_VERSION_LEN   32
#define MAX_HW_VERSION_LEN  32
    
#define TRX_MAX_OFFSET 3
    
#define MAX_FILE_NAME_LEN   16
#define MAX_PATH_LEN         40
    
#define MESSAGE_DIGEST_SIZE_V2 20
    /* 错误定义 */
#define MUT_OK                              0L
#define TSP_D_ERR_MUT_PARAMETER_ERR         0x0001
#define TSP_D_ERR_MUT_OPEN_FILE_ERR         0x0002
#define TSP_D_ERR_MUT_INTERNAL_ERR          0x0003
#define TSP_D_ERR_MUT_INPUT_IP_ERR          0x0004
#define TSP_D_ERR_MUT_READ_FILE_ERR         0x0005
#define TSP_D_ERR_MUT_FILE_STRUCT_ERR       0x0006
#define TSP_D_ERR_MUT_EOF                   0x0007
#define TSP_D_ERR_MUT_CRC_CMP_OK            0x0008
#define TSP_D_ERR_MUT_CRC_CMP_NOK           0x0009
#define TSP_D_ERR_MUT_SOCKET_ERR            0x000a
#define TSP_D_ERR_MUT_MALLOC_ERR            0x000b
#define TSP_D_ERR_MUT_SEND_PACKET_ERR       0x000c
#define TSP_D_ERR_MUT_NETCARD_NO_ERR        0x000d
#define TSP_D_ERR_MUT_OFFSET_TOO_LONG       0x000e
#define TSP_D_ERR_MUT_GET_ADAPTER_INFO_ERR  0x000f
#define TSP_D_ERR_MUT_NETCARD_IP_ERR        0x0010
#define TSP_D_ERR_MUT_IP_RESERVED           0x0011
#define TSP_D_ERR_MUT_PKGVALIDCODE_ERR      0x0012
#define TSP_D_ERR_MUT_FILEVALIDCODE_ERR     0x0013
    
#define UPG_D_ERR_MUT_NETWORK_ERR           0x0014
#define UPG_THREAD_RUN                      0x0015
#define UPG_THREAD_STOP                     0x0016
    
    /* TD侧最大文件数 */
#define MAX_TD_FILE_NUM        20
    /* HGW侧最大文件数 */
#define MAX_HGW_FILE_NUM        10
/* 升级包最大文件数 */
#define MAX_TOTAL_FILE_NUM      30
/* 升级包中射频文件魔术字 */
#define UPG_FILE_TD_FLAG 0xA55AAA55
#define UPG_FILE_HGW_FLAG 0x30524448

/* 组播包净荷长度 */
#define MULTI_BUFF_LEN (1024*2)
/*****************************************************************************/
/*  宏操作定义                                                               */
/*****************************************************************************/


/*****************************************************************************/
/*  枚举类型定义                                                             */
/*****************************************************************************/
typedef enum {
    MUPG_PACKAGE_TYPE_CPE = 1,
    MUPG_PACKAGE_TYPE_HGW,
    MUPG_PACKAGE_TYPE_MINISYS,
    MUPG_PACKAGE_TYPE_MODEM,
    MUPG_PACKAGE_TYPE_UNKNOWN,
}MUPG_PACKAGE_TYPE;

typedef enum {
    MUPG_POLICY_CPE = 1,
    MUPG_POLICY_HGW,
    MUPG_POLICY_MINISYS,
    MUPG_POLICY_MODEM,
    MUPG_POLICY_UNKNOWN,
}MUPG_POLICY_TYPE;


/*****************************************************************************/
/*  结构体类型定义                                                           */
/*****************************************************************************/
typedef struct {
    DWORD magic;        /* "HDR0" */
    DWORD len;        /* Length of file including header */
    DWORD crc32;        /* 32-bit CRC from flag_version to end of file */
    DWORD flagVersion;    /* 0:15 flags, 16:31 version */
    DWORD offsets[TRX_MAX_OFFSET];    /* Offsets of partitions from start of header */
    char productName[16];           /* 产品名称 */
    char pltVersion[32];            /* 平台软件发布版本号 */
    char swVersion[32];             /* 软件版本号 */
    char hwVersion[32];             /* 硬件版本号 */
    char uiVersion[32];             /* WEB UI版本号 */
    char reserve[112];               /* 信息保留字段存储空间 */
}TRX_HEADER;

/* 升级单元头结构 */
/* 路由器的头结构 */
typedef struct {
    unsigned int magic;        /* "HDR0" */
    unsigned int len;        /* Length of file including header */
    unsigned int crc32;        /* 32-bit CRC from flag_version to end of file */
    unsigned int flagVersion;    /* 0:15 flags, 16:31 version */
    unsigned int offsets[TRX_MAX_OFFSET];    /* Offsets of partitions from start of header */
}TrxHeader;
/* TD头结构 */
typedef struct {
    // 从这里开始9个字段和.ptt文件中每个partition的字段是一一对应的。
    unsigned int    partitionId;                               // 分区ID号
    unsigned char   partitionName[MAX_FILE_NAME_LEN];          // 分区的名称
    unsigned char   partitionPath[MAX_PATH_LEN];               // 升级文件名
    unsigned int    partitionOffset;                           // 升级文件在FLASH中的存放地址
    unsigned int    partitionSize;                             // 升级文件占用的FLASH大小，以block大小0x20000为单位
    unsigned int    partitionShadow;                           // shadow的标志位，从.ptt文件读取
    unsigned int    partitionShadowAddress;                    // shadow的起始地址
    unsigned int    partitionExecAddress;                      // 执行地址，从.ptt文件中读取
    unsigned int    partitionProtected;                        // 是否需要保护的标志位
    // 到这里结束9个字段和.ptt文件中每个partition的字段是一一对应的。
    int           partitionNumber;                             // 分区号，即为.ptt文件中的[partition#01]
    int           partitionContentSize;                        // 每个射频升级文件的实际大小
    int           partitionCrcSize;                            // 填－1
    int           partitionMargin;                             // = partition_size - partition_content_size
    int           partitionProtectedSize;                      // 填0
    // Bootnand_V2
    int           partitionShadowSize;                         // 填0
    unsigned char partitionSha1[MESSAGE_DIGEST_SIZE_V2];       // 填0
    unsigned int  partitionCrc32;                              // 每个射频文件的CRC校验值。
    unsigned char partitionSelected;                           // 表示该文件是否需要升级，目前填1
    int           numberOfPartition;                           // 射频板升级文件的总数（包括Bootnand文件!）
}PATITION_TABLE_T;

#define  GROUP_UPG_MAGIC_NUM    0xB0A555AA

// file tag (head) structure all is in clear text except validationTokens (crc, md5, sha1, etc).
// Total: 128 unsigned chars
#define TAG_LEN         256
#define TAG_VER_LEN     4
#define SIG_LEN         20
#define IMAGE_LEN       10
#define ADDRESS_LEN     12
#define FLAG_LEN        2
#define TOKEN_LEN       20
#define BOARD_ID_LEN    16
#define RESERVED_LEN    (TAG_LEN-TAG_VER_LEN-BOARD_ID_LEN-(2*SIG_LEN)- \
(4*IMAGE_LEN)-(3*ADDRESS_LEN)-(3*FLAG_LEN)-(2*TOKEN_LEN))

#define CRC_INITIAL_VALUE  0xFFFFFFFF
#define CRC_RESIDUE        0xC704DD7B /* 不能修改该值 */

#define POLYNOMIAL 0x04c11db7L /* CRC常量 */
#define DEFAULT_MULTICAST_IP    "224.0.0.119"
#define DEFAULT_INTERVAL_TIME   "1ms"

namespace UtilClass {
    const int FILE_NAME_EXTENSION_LEN = 4;
    const int INI_FILE_BUFFER_OFFSET = 12;
    const int PATITION_LEN = 1024;
    const int PATITION_PARAMETER_NUM = 3;
    const int ADDR_PARAMETER_NUM = 2;
    const int PATITION_CHECK = 1;
    const int PATITION_NOT_CHECK = 2;
    const int PATITION_NUM_MAX = 32;
    const int DECIMAL_NUM = 10;
    const int BYTE_BIT_LEN = 8;
    const int LEN_OF_PACKET_TYPE_AND_LEN = 4;
    const int PACKET_SEQUENCE_NUMBER_OFFSET = 4;
    const int PACKET_SEQUENCE_NUMBER_LEN = 4;
    const int PACKET_CRC_OFFSET = 8;
    const int PACKET_CRC_LEN = 4;
    const int PACKET_IMG_LEN_OFFSET = 12;
    const int PACKET_IMG_LEN_LEN = 4;
    const int PACKET_IMG_CRC_OFFSET = 16;
    const int PACKET_IMG_CRC_LEN = 4;
    const int PACKET_ID_OFFSET = 20;
    const int PACKET_ID_LEN = 22;
    const int PACKET_PRODUCT_ID_OFFSET = 42;
    const int PACKET_PRODUCT_ID_LEN = 20;
    const int PACKET_SEG_BUFFER_OFFSET = 62;
    const int PACKET_SEG_BUFFER_LEN = 20;
    const int INI_POSTFIX_LEN = 4;
    const int PATITION_COVER_INDEX = 2;
};

extern void MutMsTimer(unsigned long ulMsInterval);
extern unsigned long MutReadOneLine(FILE* pFile);

/* Prototype Functions */
extern unsigned long MutCrcCompute(const unsigned char *csData, unsigned long len);
extern unsigned long MutParseIniFile(const char* pszIniFileName);
extern unsigned long MutParsePkghead(const char* pszImgFileName);
extern unsigned long TspMutGetIniFileName(const char* pszPath);

extern unsigned long TspMutGetConfigInfo();
extern unsigned long MutGetImgFileCRC(FILE* pFile);
extern unsigned long MutGetFileSegment(FILE* pFilePtr, unsigned long ulPosition,
    char* pszBuff, unsigned long ulBuffSize);
extern unsigned long MutBuildPacket(const char* pszSegBuff, unsigned long ulPacketLen);
extern unsigned long MutBuildPartitionPacket(unsigned long ulPacketLen);
extern unsigned long MutBuildEndPacket(unsigned long ulPacketLen);
extern unsigned long MutGetFileLen(FILE* pFile);
extern unsigned long BuildPacket(unsigned long ulTmp, long lCRC);

#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cpluscplus */
#endif /* __cpluscplus */


#endif  /* __UTIL_H__ */
